package com.sx.service.user;

import com.sx.basic.exception.BasicException;
import com.sx.basic.service.BasicService;
import com.sx.basic.service.impl.BasicServiceImpl;
import com.sx.dao.user.AmountRepository;
import com.sx.entity.user.AmountEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author AdinZ
 * @date 2020/11/18 18:24
 */
@Service
public class AmountService extends BasicServiceImpl<AmountRepository, AmountEntity,Long>
        implements BasicService<AmountEntity,Long>,IAmountService{

    /**
     * 获取账户金额
     * @param amountType 金额类型
     * @param uid 用户id
     * @return
     */
    @Override
    public AmountEntity get(AmountEntity.AmountType amountType, long uid) {
        List<AmountEntity> amount = this.repository.findAmount(amountType, uid);
        if(amount==null) {
            //账户不存在时创建一个
            return this.createAmount(amountType,uid,BigDecimal.ZERO);
        }
        return amount.get(0);
    }

    /**
     *  创建用户金额资料
     * @param amountType 金额类型
     * @param uid 用户id
     * @param amount 初始金额
     */
    @Override @Transactional
    public AmountEntity createAmount(AmountEntity.AmountType amountType, long uid, BigDecimal amount) {
        if(amount==null) amount=BigDecimal.ZERO;
        if(amountType==null)throw new BasicException("金额类型不正确");
        final String lockKey="AMOUNT__"+amountType.name()+"__"+uid;
        try {
            if(!this.redisService.lock(lockKey)) throw new BasicException("请勿重复添加账户");
            List<AmountEntity> list = this.repository.findAmount(amountType, uid);
            if (list != null && list.size() > 0) throw new BasicException("账户金额已存在");
            AmountEntity entity = new AmountEntity();
            entity.setType(amountType);
            entity.setUid(uid);
            entity.setAmount(amount);
            entity.setBeforeAmount(BigDecimal.ZERO);
            this.save(entity);
            return entity;
        }finally {
            this.redisService.unlock(lockKey);
        }
    }

    /**
     * 账户金额变动
     * @param amountType 变动金额类型
     * @param uid 用户id
     * @param amount 变动金额, 正数 ,或负数
     */
    @Override
    public AmountEntity amountChange(AmountEntity.AmountType amountType, long uid, BigDecimal amount) {
        if(amount==null) throw new BasicException("账户金额有误");
        if(amountType==null)throw new BasicException("金额类型不正确");
        final String lockKey="AMOUNT__"+amountType.name()+"__"+uid;
        try{
            if(!this.redisService.lock(lockKey))throw new BasicException("请勿重复变动金额");
            AmountEntity entity = this.get(amountType, uid);
            entity.setBeforeAmount(entity.getAmount());
            entity.setAmount(entity.getAmount().add(amount));
            entity.setVersion(entity.getVersion()+1);
            entity.setUpdated(System.currentTimeMillis());
            if(entity.getAmount().compareTo(BigDecimal.ZERO)<0)throw new BasicException("余额不足");
            this.update(entity);
            return entity;
        }finally {
            this.redisService.unlock(lockKey);
        }
    }
}

